#pragma once
//#include "pch.h"
#include "Windows.h"

const UINT32 Invalid = 0;
const UINT32 None = 1;
const UINT32 JUNCTION = 2;
const UINT32 SYMLINK = 4;
const UINT32 SYMLINKD = 8;
const UINT32 HardLink = 16;
const UINT32 SingleFile = 32;
const UINT32 NotSupport = None | SingleFile;

struct SafeHandle {
	HANDLE Handle;
	SafeHandle();
	~SafeHandle();
	bool IsInvalid();
	void ForceClose();
};


namespace MklinkTools {
	[System::Serializable]
	[System::Flags]
	public enum class LinkType :UINT32 { Invalid = 0, None = 1, JUNCTION = 2, SYMLINK = 4, SYMLINKD = 8, HardLink = 16, SingleFile = 32, NotSupport = None | SingleFile };


	typedef struct _REPARSE_DATA_BUFFER {
		DWORD ReparseTag;
		WORD  ReparseDataLength;
		WORD  Reserved;
		union {
			struct {
				WORD SubstituteNameOffset;
				WORD SubstituteNameLength;
				WORD PrintNameOffset;
				WORD PrintNameLength;
				ULONG Flags;
				WCHAR PathBuffer[1];
			} SymbolicLinkReparseBuffer;

			struct {
				WORD SubstituteNameOffset;
				WORD SubstituteNameLength;
				WORD PrintNameOffset;
				WORD PrintNameLength;
				WCHAR PathBuffer[1];
			} MountPointReparseBuffer;

			struct {
				BYTE DataBuffer[1];
			} GenericReparseBuffer;
		};
	} REPARSE_DATA_BUFFER;


	[System::Serializable]
	public ref class GetListTypeException : System::Exception
	{
	public:
		GetListTypeException() { }
		GetListTypeException(System::String^ message) : Exception(message) { }
		GetListTypeException(System::String^ message, Exception^ inner) : Exception(message, inner) { }
	};

	public ref class GetFileInfo
	{
	public:
		static	LinkType GetFileLinkTypeUnmanaged(System::String^ Path, bool IgnorError);
		static LinkType GetFileLinkTypeManaged(System::String^ Path, bool IgnorError);
		static	array<System::String^>^ GetFilelingHardLinksUnmanaged(System::String^ Path);
		static array<System::String^>^ GetFilelingHardLinksManaged(System::String^ Path);
	};
}